package utils

import (
	"log"
	"os"
	"path/filepath"
	"sync"
	"time"
)

// RotateLog 可自动按天切换的日志
type RotateLog struct {
	sync.RWMutex
	filename string
	lastdate time.Time
	logger   *log.Logger
}

// Filename 日志文件名
func (r *RotateLog) Filename() string {
	r.RLock()
	defer r.RUnlock()
	return r.filename
}

// LastDate 最后的日志日期
func (r *RotateLog) LastDate() time.Time {
	r.RLock()
	defer r.RUnlock()
	return r.lastdate
}

// Logger 获取当前的日志，如果滚动失败则返回错误
func (r *RotateLog) Logger() (*log.Logger, error) {
	r.Lock()
	defer r.Unlock()
	now := time.Now()
	ny, nm, nd := now.Date()
	y, m, d := r.lastdate.Date()
	if ny == y && nm == m && nd == d && r.logger != nil {
		return r.logger, nil
	}
	filename := r.filename + `_` + now.Format("2006_01_02") + `.log`
	fullpath := ProjectPath() + `/logs/` + filename
	dir := filepath.Dir(fullpath)
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		err = os.MkdirAll(dir, 0755)
		if err != nil {
			return nil, err
		}
	}
	f, err := os.OpenFile(fullpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return nil, err
	}
	r.lastdate = now
	if r.logger == nil {
		r.logger = log.New(f, ``, log.LstdFlags|log.Lshortfile)
	} else {
		r.logger.SetOutput(f)
	}
	return r.logger, nil
}

// NewRotateLog 获取一个滚动日志写入器
func NewRotateLog(filename string) *RotateLog {
	r := &RotateLog{
		filename: filename,
	}
	return r
}
